<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src = "https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
</head>
<body>
<p>我是标签1</p>
<p>我是标签2</p>
<p>我是标签3</p>

<script>
    /*
    * 迭代器模式：
    *   提供一种方法，顺序访问一个聚合对象中各个元素，而又无需暴露该对象的内部表示。
    *
    * 例如下列各种集合，我们都可以用迭代器来遍历其中的内容。
    * 一个万能的遥控器，可以控制所有品牌的电视机进行换台，遍历其中的频道。
    *
    * */
    var arr = [1,2,3,4] //数组集合
    var nodeList = document.getElementsByTagName("p") //nodelist集合
    var $p = $("p") //jq集合

    //手写一个迭代器，es5的语法
    class Iterator{ //迭代器类
        constructor(list){ //接收获取到的集合对象
            this.list = list
            this.index = 0 //传入的集合对象中内容元素的下标
        }
        next(){ //迭代器迭代下一个元素的方法
            if(this.hasNext()){ //有未被遍历的元素才继续遍历
                return this.list[this.index++]
            }
            return null //否则返回空，表示没有元素了
        }
        hasNext(){ //判断该集合内是否还有写一个未被遍历的元素，如果有才能进行遍历
            if(this.index >= this.list.length){ //如果遍历的元素下标大于这个集合对象的内容长度，表明对象内所有元素都被遍历了，没有未遍历的
                return false
            }
            return true //否则返回true
        }
    }
    let iter = new Iterator(arr) //实例化迭代器对象，传入接收的集合
    let iter1 = new Iterator(nodeList)

    //每次要迭代时，就调用它的迭代方法，调用几次迭代几次
    console.log(iter.next())
    console.log(iter.next())
    console.log(iter.next())
    console.log(iter.next())
    console.log(iter.next())

    //用while循环来调用方法遍历
    while(iter1.hasNext()){
        console.log(iter1.next())
    }


    //es6方法手动封装一个遍历方法each
    function each(list){
        let iter = list[Symbol.iterator]() //list集合对象的Symbol方法返回一个函数，这个函数执行，使其返回一个迭代器给iter
        console.log(iter)
        console.log(iter.next()) //next是迭代器自带的方法，看看有没有下一个需要遍历的元素

        let item = {done:false} //写一个标识，默认为false，表示未遍历完成
        while(!iter.done){
            item = iter.next()
            if(!item.done){
                console.log(item.value)
            }
        }
    }

    let map = new Map() //实例生成一个对象map
    map.set("a",1) //往map对象中创建键值对
    map.set("b",2)
    each(map) //each函数中传入map集合对象，就可以迭代

    //如果不想写迭代器，es6的语法糖for of就行
    for(i of arr){
        //遍历即可
    }
    for(i of nodeList)

</script>
</body>
</html>